// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
// ------------------------------------------------------------

#include "stdafx.h"

BOOL APIENTRY DllMain(
    HMODULE module,
    DWORD reason,
    LPVOID reserved)
{
    UNREFERENCED_PARAMETER(reserved);
    UNREFERENCED_PARAMETER(module);

    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

//
// WARNING: 
//
// The signature below MUST exactly match (including the parameter names)
// with the signature generated by MIDL in the FabricClient.h file. 
// Otherwise the linker does not apply the extern "C" specifier and exports 
// this function as C++ name mangled function instead of C style function.
// 

/* [entry] */ HRESULT FabricBeginCreateRuntime( 
    /* [in] */ __RPC__in REFIID riid,
    /* [in] */ __RPC__in_opt IFabricProcessExitHandler *exitHandler,
    /* [in] */ DWORD timeoutMilliseconds,
    /* [in] */ __RPC__in_opt IFabricAsyncOperationCallback *callback,
    /* [retval][out] */ __RPC__deref_out_opt IFabricAsyncOperationContext **context)
{
    Common::DllConfig::GetConfig();

    return Hosting2::ApplicationHostContainer::FabricBeginCreateRuntime(riid, exitHandler, timeoutMilliseconds, callback, context);
}

/* [entry] */ HRESULT FabricEndCreateRuntime( 
    /* [in] */ __RPC__in_opt IFabricAsyncOperationContext *context,
    /* [retval][out] */ __RPC__deref_out_opt void **fabricRuntime)
{
    return Hosting2::ApplicationHostContainer::FabricEndCreateRuntime(context, fabricRuntime);
}

/* [entry] */ HRESULT FabricCreateRuntime( 
    /* [in] */ __RPC__in REFIID riid,
    /* [retval][out] */ __RPC__deref_out_opt void **fabricRuntime)
{
    Common::DllConfig::GetConfig();

    return Hosting2::ApplicationHostContainer::FabricCreateRuntime(riid, fabricRuntime);
}

/* [entry] */ HRESULT FabricBeginGetActivationContext( 
    /* [in] */ __RPC__in REFIID riid,
    /* [in] */ DWORD timeoutMilliseconds,
    /* [in] */ __RPC__in_opt IFabricAsyncOperationCallback *callback,
    /* [retval][out] */ __RPC__deref_out_opt IFabricAsyncOperationContext **context)
{
    Common::DllConfig::GetConfig();

    return Hosting2::ApplicationHostContainer::FabricBeginGetActivationContext(riid, timeoutMilliseconds, callback, context);
}

/* [entry] */ HRESULT FabricEndGetActivationContext( 
    /* [in] */ __RPC__in_opt IFabricAsyncOperationContext *context,
    /* [retval][out] */ __RPC__deref_out_opt void **activationContext)
{
    Common::DllConfig::GetConfig();

    return Hosting2::ApplicationHostContainer::FabricEndGetActivationContext(context, activationContext);
}

/* [entry] */ HRESULT FabricGetActivationContext( 
    /* [in] */ __RPC__in REFIID riid,
    /* [retval][out] */ __RPC__deref_out_opt void **activationContext)
{
    Common::DllConfig::GetConfig();

    return Hosting2::ApplicationHostContainer::FabricGetActivationContext(riid, activationContext);
}

/* [entry] */ HRESULT FabricRegisterCodePackageHost( 
    /* [in] */ __RPC__in_opt IUnknown *codePackageHost)
{
    Common::DllConfig::GetConfig();

    return Hosting2::ApplicationHostContainer::FabricRegisterCodePackageHost(codePackageHost);
}

/* [entry] */ HRESULT FabricCreateKeyValueStoreReplica( 
    /* [in] */ __RPC__in REFIID riid,
    /* [in] */ __RPC__in LPCWSTR storeName,
    /* [in] */ FABRIC_PARTITION_ID partitionId,
    /* [in] */ FABRIC_REPLICA_ID replicaId,
    /* [in] */ __RPC__in const FABRIC_REPLICATOR_SETTINGS *replicatorSettings,
    /* [in] */ FABRIC_LOCAL_STORE_KIND localStoreKind,
    /* [in] */ __RPC__in void *localStoreSettings,
    /* [in] */ __RPC__in_opt IFabricStoreEventHandler *storeEventHandler,
    /* [retval][out] */ __RPC__deref_out_opt void **keyValueStore)
{
    return FabricCreateKeyValueStoreReplica2(
            riid,
            storeName,
            partitionId,
            replicaId,
            replicatorSettings,
            localStoreKind,
            localStoreSettings,
            storeEventHandler,
            NULL,
            FABRIC_KEY_VALUE_STORE_NOTIFICATION_MODE_NONE,
            keyValueStore);
}

/* [entry] */ HRESULT FabricCreateKeyValueStoreReplica2(
    /* [in] */ __RPC__in REFIID riid,
    /* [in] */ __RPC__in LPCWSTR storeName,
    /* [in] */ FABRIC_PARTITION_ID partitionId,
    /* [in] */ FABRIC_REPLICA_ID replicaId,
    /* [in] */ __RPC__in const FABRIC_REPLICATOR_SETTINGS *replicatorSettings,
    /* [in] */ FABRIC_LOCAL_STORE_KIND localStoreKind,
    /* [in] */ __RPC__in void *localStoreSettings,
    /* [in] */ __RPC__in_opt IFabricStoreEventHandler *storeEventHandler,
    /* [in] */ __RPC__in_opt IFabricSecondaryEventHandler *secondaryEventHandler,
    /* [in] */ FABRIC_KEY_VALUE_STORE_NOTIFICATION_MODE notificationMode,
    /* [retval][out] */ __RPC__deref_out_opt void **keyValueStore)
{
    return FabricCreateKeyValueStoreReplica3(
        riid,
        storeName,
        partitionId,
        replicaId,
        replicatorSettings,
        localStoreKind,
        localStoreSettings,
        storeEventHandler,
        secondaryEventHandler,
        notificationMode,
        keyValueStore);
}

/* [entry] */ HRESULT FabricCreateKeyValueStoreReplica3( 
    /* [in] */ __RPC__in REFIID riid,
    /* [in] */ __RPC__in LPCWSTR storeName,
    /* [in] */ FABRIC_PARTITION_ID partitionId,
    /* [in] */ FABRIC_REPLICA_ID replicaId,
    /* [in] */ __RPC__in const FABRIC_REPLICATOR_SETTINGS *replicatorSettings,
    /* [in] */ FABRIC_LOCAL_STORE_KIND localStoreKind,
    /* [in] */ __RPC__in void *localStoreSettings,
    /* [in] */ __RPC__in_opt IFabricStoreEventHandler *storeEventHandler,
    /* [in] */ __RPC__in_opt IFabricSecondaryEventHandler *secondaryEventHandler,
    /* [in] */ FABRIC_KEY_VALUE_STORE_NOTIFICATION_MODE notificationMode,
    /* [retval][out] */ __RPC__deref_out_opt void **keyValueStore)
{
    return FabricCreateKeyValueStoreReplica4(
        riid,
        storeName,
        partitionId,
        replicaId,
        NULL,
        replicatorSettings,
        localStoreKind,
        localStoreSettings,
        storeEventHandler,
        secondaryEventHandler,
        notificationMode,
        keyValueStore);
}

INIT_ONCE clientFactoryInitOnce = INIT_ONCE_STATIC_INIT;
Common::Global<Api::IClientFactoryPtr> globalClientFactory;

BOOL CALLBACK CreateGlobalClientFactory(PINIT_ONCE, PVOID, PVOID *)
{
    auto nodeConfig = std::make_shared<Common::FabricNodeConfig>();

    Api::IClientFactoryPtr clientFactory;
    auto error = Client::ClientFactory::CreateLocalClientFactory(nodeConfig, clientFactory);

    if (error.IsSuccess())
    {
        globalClientFactory = Common::make_global<Api::IClientFactoryPtr>(clientFactory);

        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
    
Api::IClientFactoryPtr GetGlobalClientFactory()
{
    PVOID lpContext = NULL;
    BOOL success = ::InitOnceExecuteOnce(
        &clientFactoryInitOnce,
        CreateGlobalClientFactory,
        NULL,
        &lpContext);

    if (success)
    {
        return *globalClientFactory;
    }
    else
    {
        // best effort
        return Api::IClientFactoryPtr();
    }
}

/* [entry] */ HRESULT FabricCreateKeyValueStoreReplica4( 
    /* [in] */ __RPC__in REFIID riid,
    /* [in] */ __RPC__in LPCWSTR storeName,
    /* [in] */ FABRIC_PARTITION_ID partitionId,
    /* [in] */ FABRIC_REPLICA_ID replicaId,
    /* [in] */ FABRIC_URI serviceName,
    /* [in] */ __RPC__in const FABRIC_REPLICATOR_SETTINGS *replicatorSettings,
    /* [in] */ FABRIC_LOCAL_STORE_KIND localStoreKind,
    /* [in] */ __RPC__in void *localStoreSettings,
    /* [in] */ __RPC__in_opt IFabricStoreEventHandler *storeEventHandler,
    /* [in] */ __RPC__in_opt IFabricSecondaryEventHandler *secondaryEventHandler,
    /* [in] */ FABRIC_KEY_VALUE_STORE_NOTIFICATION_MODE notificationMode,
    /* [retval][out] */ __RPC__deref_out_opt void **keyValueStore)
{
    FABRIC_KEY_VALUE_STORE_REPLICA_SETTINGS kvsSettings = { 0 };
    kvsSettings.SecondaryNotificationMode = notificationMode;

    return FabricCreateKeyValueStoreReplica5(
        riid,
        storeName,
        partitionId,
        replicaId,
        serviceName,
        replicatorSettings,
        &kvsSettings,
        localStoreKind,
        localStoreSettings,
        storeEventHandler,
        secondaryEventHandler,
        keyValueStore);
}

/* [entry] */ HRESULT FabricCreateKeyValueStoreReplica5( 
    /* [in] */ __RPC__in REFIID riid,
    /* [in] */ __RPC__in LPCWSTR storeName,
    /* [in] */ FABRIC_PARTITION_ID partitionId,
    /* [in] */ FABRIC_REPLICA_ID replicaId,
    /* [in] */ FABRIC_URI serviceName,
    /* [in] */ __RPC__in const FABRIC_REPLICATOR_SETTINGS *replicatorSettings,
    /* [in] */ __RPC__in const FABRIC_KEY_VALUE_STORE_REPLICA_SETTINGS *kvsSettings,
    /* [in] */ FABRIC_LOCAL_STORE_KIND localStoreKind,
    /* [in] */ __RPC__in void *localStoreSettings,
    /* [in] */ __RPC__in_opt IFabricStoreEventHandler *storeEventHandler,
    /* [in] */ __RPC__in_opt IFabricSecondaryEventHandler *secondaryEventHandler,
    /* [retval][out] */ __RPC__deref_out_opt void **keyValueStore)
{
    Common::DllConfig::GetConfig();

    auto clientFactory = GetGlobalClientFactory();

    auto factoryImpl = std::make_shared<Store::KeyValueStoreReplicaFactory>();
    Api::ComKeyValueStoreReplicaFactory comFactory(
        Api::IKeyValueStoreReplicaFactoryPtr(
            (Api::IKeyValueStoreReplicaFactory*)factoryImpl.get(),
            factoryImpl->CreateComponentRoot()));

    return comFactory.FabricCreateKeyValueStoreReplica(
            riid,
            storeName,
            partitionId,
            replicaId,
            serviceName,
            replicatorSettings,
            kvsSettings,
            localStoreKind,
            localStoreSettings,
            storeEventHandler,
            secondaryEventHandler,
            clientFactory,
            keyValueStore);
}

/* [entry] */ HRESULT FabricCreateKeyValueStoreReplica_V2( 
    /* [in] */ __RPC__in REFIID riid,
    /* [in] */ FABRIC_PARTITION_ID partitionId,
    /* [in] */ FABRIC_REPLICA_ID replicaId,
    /* [in] */ __RPC__in const FABRIC_KEY_VALUE_STORE_REPLICA_SETTINGS_V2 *storeSettings,
    /* [in] */ __RPC__in const FABRIC_REPLICATOR_SETTINGS *replicatorSettings,
    /* [in] */ __RPC__in_opt IFabricStoreEventHandler *storeEventHandler,
    /* [in] */ __RPC__in_opt IFabricSecondaryEventHandler *secondaryEventHandler,
    /* [retval][out] */ __RPC__deref_out_opt void **keyValueStore)
{
    Common::DllConfig::GetConfig();

    auto factoryImpl = std::make_shared<Store::KeyValueStoreReplicaFactory>();
    Api::ComKeyValueStoreReplicaFactory comFactory(
        Api::IKeyValueStoreReplicaFactoryPtr(
            (Api::IKeyValueStoreReplicaFactory*)factoryImpl.get(),
            factoryImpl->CreateComponentRoot()));

    return comFactory.FabricCreateKeyValueStoreReplica_V2(
            riid,
            partitionId,
            replicaId,
            storeSettings,
            replicatorSettings,
            storeEventHandler,
            secondaryEventHandler,
            keyValueStore);
}

/* [entry] */ HRESULT FabricBeginGetNodeContext( 
    /* [in] */ DWORD timeoutMilliseconds,
    /* [in] */ __RPC__in_opt IFabricAsyncOperationCallback *callback,
    /* [retval][out] */ __RPC__deref_out_opt IFabricAsyncOperationContext **context)
{
    Common::DllConfig::GetConfig();

    return Hosting2::ApplicationHostContainer::FabricBeginGetNodeContext(timeoutMilliseconds, callback, context);
}


/* [entry] */ HRESULT FabricEndGetNodeContext( 
    /* [in] */ __RPC__in_opt IFabricAsyncOperationContext *context,
    /* [retval][out] */ __RPC__deref_out_opt void **nodeContext)
{
    Common::DllConfig::GetConfig();

    return Hosting2::ApplicationHostContainer::FabricEndGetNodeContext(context, nodeContext);
}

/* [entry] */ HRESULT FabricGetNodeContext( 
    /* [retval][out] */ __RPC__deref_out_opt void **nodeContext)
{
    Common::DllConfig::GetConfig();

    return Hosting2::ApplicationHostContainer::FabricGetNodeContext(nodeContext);
}

#if !defined(PLATFORM_UNIX)
/* [entry] */ HRESULT FabricGetRuntimeDllVersion( 
    /* [out] */ __RPC__deref_out_opt IFabricStringResult **runtimeDllVersion)
{
    Common::DllConfig::GetConfig();

    std::wstring result;
    auto error = Common::Environment::GetCurrentModuleFileVersion2(result);

    if(error.IsSuccess())
    {
        return Common::ComStringResult::ReturnStringResult(result, runtimeDllVersion);
    }
    else
    {
        return Common::ComUtility::OnPublicApiReturn(error.ToHResult());
    }
}
#endif

/* [entry] */ HRESULT FabricLoadReplicatorSettings(
    /* [in] */ __RPC__in IFabricCodePackageActivationContext const * codePackageActivationContext,
    /* [in] */ __RPC__in LPCWSTR configurationPackageName,
    /* [in] */ __RPC__in LPCWSTR sectionName,
    /* [retval][out] */ __RPC__deref_out_opt IFabricReplicatorSettingsResult ** replicatorSettings)
{
    Common::ComPointer<IFabricCodePackageActivationContext> codePackageActivationContextCPtr;
    Common::ComPointer<IFabricCodePackageActivationContext6> codePackageActivationContext6CPtr;
    std::wstring sectionNameW; 
    std::wstring configurationPackageNameW; 
    std::wstring hostName;
    Common::ComPointer<IFabricNodeContextResult2> nodeContext;
    std::wstring publishHostName;

    HRESULT hr = Hosting2::ApplicationHostContainer::FabricGetNodeContext(nodeContext.VoidInitializationAddress());
    if (hr != S_OK)
    {
        return Common::ComUtility::OnPublicApiReturn(hr);
    }

    if (nodeContext->get_NodeContext() == nullptr)
    {
        return Common::ComUtility::OnPublicApiReturn(E_POINTER);
    }

    hr = Common::StringUtility::LpcwstrToWstring(sectionName, false, sectionNameW);
    if (hr != S_OK)
    {
        return Common::ComUtility::OnPublicApiReturn(hr);
    }

    hr = Common::StringUtility::LpcwstrToWstring(configurationPackageName, false, configurationPackageNameW);
    if (hr != S_OK)
    {
        return Common::ComUtility::OnPublicApiReturn(hr);
    }

    codePackageActivationContextCPtr.SetAndAddRef(const_cast<IFabricCodePackageActivationContext *>(codePackageActivationContext));

    hr = codePackageActivationContextCPtr->QueryInterface(
        IID_IFabricCodePackageActivationContext6,
        codePackageActivationContext6CPtr.VoidInitializationAddress());
    if (hr != S_OK)
    {
        return Common::ComUtility::OnPublicApiReturn(hr);
    }

    hostName = codePackageActivationContext6CPtr->get_ServiceListenAddress();
    publishHostName = codePackageActivationContext6CPtr->get_ServicePublishAddress();

    return Common::ComUtility::OnPublicApiReturn(
        Reliability::ReplicationComponent::ReplicatorSettings::FromConfig(
            codePackageActivationContextCPtr,
            configurationPackageNameW,
            sectionNameW,
            hostName,
            publishHostName,
            replicatorSettings));
}


/* [entry] */ HRESULT FabricLoadTransactionalReplicatorSettings(
    /* [in] */ __RPC__in IFabricCodePackageActivationContext const * codePackageActivationContext,
    /* [in] */ __RPC__in LPCWSTR configurationPackageName,
    /* [in] */ __RPC__in LPCWSTR sectionName,
    /* [retval][out] */ __RPC__deref_out_opt IFabricTransactionalReplicatorSettingsResult ** replicatorSettings)
{
    Common::ComPointer<IFabricCodePackageActivationContext> codePackageActivationContextCPtr;
    std::wstring sectionNameW;
    std::wstring configurationPackageNameW;

    HRESULT hr = Common::StringUtility::LpcwstrToWstring(sectionName, false, sectionNameW);
    if (hr != S_OK)
    {
        return Common::ComUtility::OnPublicApiReturn(hr);
    }

    hr = Common::StringUtility::LpcwstrToWstring(configurationPackageName, false, configurationPackageNameW);
    if (hr != S_OK)
    {
        return Common::ComUtility::OnPublicApiReturn(hr);
    }

    codePackageActivationContextCPtr.SetAndAddRef(const_cast<IFabricCodePackageActivationContext *>(codePackageActivationContext));
    return Common::ComUtility::OnPublicApiReturn(
        TxnReplicator::TransactionalReplicatorSettings::FromConfig(
            codePackageActivationContextCPtr,
            configurationPackageNameW,
            sectionNameW,
            replicatorSettings));
}

/* [entry] */ HRESULT FabricLoadSecurityCredentials(
    /* [in] */ __RPC__in IFabricCodePackageActivationContext const * codePackageActivationContext,
    /* [in] */ __RPC__in LPCWSTR configurationPackageName,
    /* [in] */ __RPC__in LPCWSTR sectionName,
    /* [retval][out] */ __RPC__deref_out_opt IFabricSecurityCredentialsResult ** securityCredentials)
{
    Common::ComPointer<IFabricCodePackageActivationContext> codePackageActivationContextCPtr;
    std::wstring sectionNameW; 
    std::wstring configurationPackageNameW; 

    HRESULT hr = Common::StringUtility::LpcwstrToWstring(sectionName, false, sectionNameW);
    if (hr != S_OK)
    {
        return Common::ComUtility::OnPublicApiReturn(hr);
    }

    hr = Common::StringUtility::LpcwstrToWstring(configurationPackageName, false, configurationPackageNameW);
    if (hr != S_OK)
    {
        return Common::ComUtility::OnPublicApiReturn(hr);
    }

    codePackageActivationContextCPtr.SetAndAddRef(const_cast<IFabricCodePackageActivationContext *>(codePackageActivationContext));
    return Common::ComUtility::OnPublicApiReturn(
        Transport::ComSecurityCredentialsResult::FromConfig(
            codePackageActivationContextCPtr,
            configurationPackageNameW,
            sectionNameW,
            securityCredentials));
}

/* [entry] */ HRESULT FabricLoadEseLocalStoreSettings(
    /* [in] */ __RPC__in IFabricCodePackageActivationContext const * codePackageActivationContext,
    /* [in] */ __RPC__in LPCWSTR configurationPackageName,
    /* [in] */ __RPC__in LPCWSTR sectionName,
    /* [retval][out] */ __RPC__deref_out_opt IFabricEseLocalStoreSettingsResult ** settingsResult)
{
    Common::RootedObjectPointer<Api::IEseLocalStoreSettingsResult> ptr;
    auto hr = Store::EseLocalStoreSettings::FromConfig(
        codePackageActivationContext,
        configurationPackageName,
        sectionName,
        ptr);
    if (hr != S_OK) { return Common::ComUtility::OnPublicApiReturn(hr); }

    auto cPtr = Api::WrapperFactory::create_com_wrapper(ptr);
    return cPtr->QueryInterface(IID_IFabricEseLocalStoreSettingsResult, reinterpret_cast<void**>(settingsResult));
}

/* [entry] */ HRESULT GetFabricKeyValueStoreReplicaDefaultSettings( 
    /* [retval][out] */ __RPC__deref_out_opt IFabricKeyValueStoreReplicaSettingsResult **result)
{
    if (result == NULL)
    {
        return Common::ComUtility::OnPublicApiReturn(E_POINTER);
    }

    Common::DllConfig::GetConfig();

    auto resultCPtr = Api::WrapperFactory::create_com_wrapper(Store::ReplicatedStoreSettings::CreateDefaultSettings());

    *result = resultCPtr.DetachNoRelease();

    return S_OK;
}

/* [entry] */ HRESULT GetFabricKeyValueStoreReplicaDefaultSettings_V2( 
    /* [in] */ LPCWSTR workingDirectory,
    /* [in] */ LPCWSTR sharedLogDirectory,
    /* [in] */ LPCWSTR sharedLogFileName,
    /* [in] */ GUID sharedLogGuid,
    /* [retval][out] */ __RPC__deref_out_opt IFabricKeyValueStoreReplicaSettings_V2Result **result)
{
    if (result == NULL)
    {
        return Common::ComUtility::OnPublicApiReturn(E_POINTER);
    }

    Common::DllConfig::GetConfig();

    TRY_COM_PARSE_PUBLIC_STRING( workingDirectory );
    TRY_COM_PARSE_PUBLIC_STRING_ALLOW_NULL( sharedLogDirectory );
    TRY_COM_PARSE_PUBLIC_STRING_ALLOW_NULL( sharedLogFileName );

    auto resultCPtr = Api::WrapperFactory::create_com_wrapper(Store::TSReplicatedStoreSettings::GetKeyValueStoreReplicaDefaultSettings(
        parsed_workingDirectory,
        parsed_sharedLogDirectory,
        parsed_sharedLogFileName,
        Common::Guid(sharedLogGuid)));

    *result = resultCPtr.DetachNoRelease();

    return S_OK;
}

/* [entry] */ HRESULT GetFabricSharedLogDefaultSettings( 
    /* [in] */ LPCWSTR workingDirectory,
    /* [in] */ LPCWSTR sharedLogDirectory,
    /* [in] */ LPCWSTR sharedLogFileName,
    /* [in] */ GUID sharedLogGuid,
    /* [retval][out] */ __RPC__deref_out_opt IFabricSharedLogSettingsResult **result)
{
    if (result == NULL)
    {
        return Common::ComUtility::OnPublicApiReturn(E_POINTER);
    }

    Common::DllConfig::GetConfig();

    TRY_COM_PARSE_PUBLIC_STRING( workingDirectory );
    TRY_COM_PARSE_PUBLIC_STRING_ALLOW_NULL( sharedLogDirectory );
    TRY_COM_PARSE_PUBLIC_STRING_ALLOW_NULL( sharedLogFileName );

    auto resultCPtr = Api::WrapperFactory::create_com_wrapper(TxnReplicator::KtlLoggerSharedLogSettings::GetKeyValueStoreReplicaDefaultSettings(
        parsed_workingDirectory,
        parsed_sharedLogDirectory,
        parsed_sharedLogFileName,
        Common::Guid(sharedLogGuid)));

    *result = resultCPtr.DetachNoRelease();

    return S_OK;
}

/* [entry] */ HRESULT FabricLoadClusterSecurityCredentials(
    /* [retval][out] */ __RPC__deref_out_opt IFabricSecurityCredentialsResult ** securityCredentials)
{   
    return Common::ComUtility::OnPublicApiReturn(
        Transport::ComSecurityCredentialsResult::ClusterSecuritySettingsFromConfig(
        securityCredentials));
}

void FabricDisableIpcLeasing(void)
{
    Hosting2::LeaseMonitor::DisableIpcLeasePolling();
}
 
/* [entry] */ HRESULT FabricCreateBackupRestoreAgent( 
    /* [in] */ __RPC__in REFIID riid,
    /* [retval][out] */ __RPC__deref_out_opt void **backupRestoreAgent)
{
    Common::DllConfig::GetConfig();
    return Hosting2::ApplicationHostContainer::FabricCreateBackupRestoreAgent(riid, backupRestoreAgent);
}

struct ReliableCollectionApis;
void GetReliableCollectionImplApiTable(ReliableCollectionApis* reliableCollectionApis);
void GetReliableCollectionMockApiTable(ReliableCollectionApis* reliableCollectionApis);

extern "C" HRESULT FabricGetReliableCollectionApiTable(uint16_t apiVersion, ReliableCollectionApis* reliableCollectionApis)
{
    UNREFERENCED_PARAMETER(apiVersion);
    wstring env;

    if (apiVersion > 0x100)
        return E_NOTIMPL;

    if (reliableCollectionApis == nullptr)
        return E_INVALIDARG;

    if (Environment::GetEnvironmentVariable(L"SF_RELIABLECOLLECTION_MOCK", env, NOTHROW()))
        GetReliableCollectionMockApiTable(reliableCollectionApis);
    else
        GetReliableCollectionImplApiTable(reliableCollectionApis);

    return S_OK;
}
